﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace chessLogic
{
    public enum FigureColor
    { 
        White,
        Black
    }
    public enum FigureType
    { 
        Pawn,
        Bishop,
        Knight,
        Rook,
        Queen,
        King,
        None
    }
    public abstract class Figure
    {
        private FigureColor color;
        private FigureType type;
        private List<string> movesMaked;

        public FigureColor Color { get { return this.color; } }
        public FigureType Type { get { return this.type; } }
        public List<string> MovesMaked { get { return this.movesMaked; } }

        public Figure(FigureColor _color, FigureType _type)
        {
            this.color = _color;
            this.type = _type;
            this.movesMaked = new List<string>();
        }
        public char TypeToChar()
        {
            switch (this.type)
            { 
                case FigureType.Knight:
                    return 'N';
                case FigureType.Bishop:
                    return 'B';
                case FigureType.Rook:
                    return 'R';
                case FigureType.Queen:
                    return 'Q';
                case FigureType.Pawn:
                    return 'p';
                case FigureType.King:
                    return 'K';
                default:
                    return ' ';
            }
        }
        public bool EqualsColor(Figure figure)
        {
            return this.color == figure.Color;
        }
        public bool Equals(Figure figure)
        {
            return (this.Type == figure.Type) && figure.EqualsColor(this);
        }
        public void AddMovesMaked(string moveString)
        {
            this.movesMaked.Add(moveString);
        }

        public abstract List<Position> GetPossiblyPositionNormalMove(Position position, Board board);
        public abstract List<Position> GetPossiblyPositionTakingMove(Position position, Board board);
        
        protected List<Position> getRookPositions(Position position, Board board)
        {
            List<Position> positions = new List<Position>();
            positions.AddRange(GetCyclePositions(1, 0, position, board).ToArray());
            positions.AddRange(GetCyclePositions(-1, 0, position, board).ToArray());
            positions.AddRange(GetCyclePositions(0, 1, position, board).ToArray());
            positions.AddRange(GetCyclePositions(0, -1, position, board).ToArray());
            return positions;
        }
        protected List<Position> getBishopPositions(Position position, Board board)
        {
            List<Position> positions = new List<Position>();
            positions.AddRange(GetCyclePositions(1, 1, position, board).ToArray());
            positions.AddRange(GetCyclePositions(1, -1, position, board).ToArray());
            positions.AddRange(GetCyclePositions(-1, 1, position, board).ToArray());
            positions.AddRange(GetCyclePositions(-1, -1, position, board).ToArray());
            return positions;
        }
        protected List<Position> getNeedPositions(List<Position> positions, bool taking, Board board)
        {
            List<Position> possiblyPositions = new List<Position>();
            foreach (Position pos in positions)
                if (board.IsPositionEmpty(pos) == !taking)
                    possiblyPositions.Add(pos);
            return possiblyPositions;
        }
        private List<Position> GetCyclePositions(int topBot, int rightLeft,
                                                Position position, Board board)
        {
            List<Position> retPos = new List<Position>();
            Position pos = new Position(position.Letter, position.Number);
            string letters = "XXabcdefghXX";
            int indexChar = letters.IndexOf(pos.Letter);
            int indexNum = pos.Number;
            int increaseIndex = 1;
            while (true)
            {
                pos.setPosition(letters[indexChar + increaseIndex * rightLeft], indexNum + increaseIndex * topBot);
                if (!pos.IsOnBoard())
                    break;
                if (board.IsPositionEmpty(pos))
                    retPos.Add(new Position(pos.Letter, pos.Number));
                else
                    if (board.getFigure(pos).EqualsColor(this))
                        break;
                    else
                    {
                        retPos.Add(new Position(pos.Letter, pos.Number));
                        break;
                    }
                increaseIndex++;
            }
            return retPos;
        }
    }
    public class None : Figure
    {
        public None() : base(FigureColor.White, FigureType.None) { }
        public override List<Position> GetPossiblyPositionNormalMove(Position position, Board board)
        { return null; }
        public override List<Position> GetPossiblyPositionTakingMove(Position position, Board board)
        { return null; }
    }
    public class King : Figure
    {
        public King(FigureColor color) : base(color, FigureType.King) { }
        public override List<Position> GetPossiblyPositionNormalMove(Position position, Board board)
        { return null; }
        public override List<Position> GetPossiblyPositionTakingMove(Position position,Board board)
        { return null; }
    }
}
